package com.authine.cloudpivot.ext.sso;

import cn.hutool.http.ContentType;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.XML;
import com.authine.cloudpivot.engine.api.model.organization.UserModel;
import com.authine.cloudpivot.web.sso.security.BaseAuthenticationToken;
import com.authine.cloudpivot.web.sso.template.BaseSimpleTemplate;
import com.authine.cloudpivot.web.sso.template.ResponseTypeEnum;
import com.authine.cloudpivot.web.sso.template.SimpleTemplateConfig;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpMethod;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.stereotype.Component;

/**
 * @Author hxd
 * @Date 2021/11/3 14:13
 * @Description oa sso
 **/
@Component
@Slf4j
public class OaSsoConfig extends BaseSimpleTemplate {

    @Value("${cloudpivot.sso.checkTicketUrl:http://10.2.56.235/api/sys-authentication/loginService/getTokenLoginName}")
    private String checkTicketUrl;

    @Value("${cloudpivot.sso.ticket_password:1}")
    private String ticketPassword;

    @Value("${cloudpivot.sso.ticket_username:110656}")
    private String ticketUsername;


    OaSsoConfig() {
        super(SimpleTemplateConfig.builder()
                .requestMatcher(new AntPathRequestMatcher("/login/mszqoa", HttpMethod.GET.name()))
                .responseType(ResponseTypeEnum.JSON)
                .redirectClientID("api")    //云枢OAuth2登录的ClientId  具体体现在base_security_client表中
                //成功后回调地址   会优先从url中获取redirect_uri，login_fail_redirect_uri。若url中无法携带，可使用默认配置 http://120.24.79.179/admin/#/apps/model/harry/aaa/dispatcher 需要在后台添加白名单
                ///oauth/authorize?client_id=api&response_type=code&scope=read为固定
                .loginPassredirectUrl("/workflow-center/my-unfinished-workitem")
                .loginFailRedirectUri("/websso/index.html")
                .build());
    }

    @Override
    public String getSourceId(final BaseAuthenticationToken token) throws Exception {

        String code = token.getCode();
        log.info( "获取 oa sso token:{}",code);
        if (code == null) {
           throw  new RuntimeException("oa sso token is null");
        }
        String rst = HttpUtil.createPost(checkTicketUrl)
                .contentType(ContentType.FORM_URLENCODED.toString())
                .basicAuth(ticketUsername, ticketPassword)
                .form("token", code)
                .timeout(600000).execute().body();

        JSONObject rstObj = XML.toJSONObject(rst);

        if (rstObj.containsKey("RestResponse")){
            err(rstObj.getJSONObject("RestResponse").getStr("msg"));
        }else  if (rstObj.containsKey("TokenLoginNameResult")){
            JSONObject result = rstObj.getJSONObject("TokenLoginNameResult");

            if (result.getBool("result")){
                return result.getStr("loginName");
            }else {
               err( result.getStr("errorMsg"));
            }

        }else {
            err(rst);
        }

        return null;
    }

    @Override
    public UserModel getUser(final Object sourceId) {

        log.info("oa 单点登录用户:{}",sourceId);

        if (sourceId == null) {
            throw  new RuntimeException("oa 单点登录用户不能为空");
        }

        UserModel user = dubboConfigService.getSystemSecurityFacade().getUserByUsername(sourceId.toString());

        if (user == null) {
            throw  new RuntimeException(String.format("oa 单点登录用户=%s在云枢组织中不存在", sourceId.toString()));
        }

        log.info("oa 单点登录成功,用户:{}",sourceId);

        return user;
    }


    private void err(String msg){
        String err = "单点登录校验oa token 失败:%s,ticketUsername=%s,ticketPassword=%s";
        throw  new RuntimeException(String.format(err, msg,ticketUsername,ticketPassword));
    }

}
